package com.michaelbulava.TFS.ui.config;

import com.intellij.openapi.ui.DialogWrapper;
import com.michaelbulava.TFS.ui.dialogs.connect.CredentialsCompleteDialog;
import com.microsoft.tfs.core.httpclient.Credentials;

/**
 * Created by mbulava on 5/6/2015.
 */
public abstract class UITransportAuthRunnable implements Runnable {
    private final Object lock = new Object();
    private Credentials credentials;
    private boolean complete = false;

    public Credentials getCredentials(){
        synchronized (lock){
            return this.credentials;
        }
    }

    /**
     * When an object implementing interface <code>Runnable</code> is used to create a thread, starting the thread
     * causes the object's <code>run</code> method to be called in that separately executing thread.
     * <p/>
     * The general contract of the method <code>run</code> is that it may take any action whatsoever.
     *
     * @see Thread#run()
     */
    @Override
    public void run() {
        synchronized (lock){
            if (complete)
                return;
        }
        final CredentialsCompleteDialog credentialsDialog = getCredentialsDialog();
        if (credentialsDialog == null){
            setComplete(null);
            return;
        }
        credentialsDialog.addCredentialsCompleteListener(new CredentialsCompleteDialog.CredentialsCompleteListener() {
            @Override
            public void credentialsComplete() {
                Credentials credentials = credentialsDialog.getExitCode() == DialogWrapper.OK_EXIT_CODE ?
                        credentialsDialog.getCredentials() : null;
                setComplete(credentials);
            }
        });
        credentialsDialog.show();
        if(credentialsDialog.getExitCode() != DialogWrapper.OK_EXIT_CODE)
            setComplete(null);
    }

    public final boolean isComplete() {
        synchronized (this.lock)
        {
            return this.complete;
        }
    }

    public final void join() throws InterruptedException{
        while(true){
            synchronized (lock){
                if (complete)
                    return;
                lock.wait();
            }
        }
    }

    private void setComplete(Credentials credentials) {
        synchronized (this.lock) {
            this.credentials = credentials;
            this.complete = true;

            this.lock.notifyAll();
        }
    }



    protected abstract CredentialsCompleteDialog getCredentialsDialog();
}
